home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / wgdb-42.lha / wgdb-4.2 / gdb / rem-multi.shar < prev    next >
Text File  |  1992-09-11  |  31KB  |  1,314 lines

  1. #!/bin/sh
  2. #    This is a shell archive.
  3. #    Run the file through sh to extract its contents.
  4. # shar:    Shell Archiver
  5. #    Run the following text with /bin/sh to create:
  6. #    Remote_Makefile
  7. #    remote_gutils.c
  8. #    remote_inflow.c
  9. #    remote_server.c
  10. #    remote_utils.c
  11. # This archive created: Fri Jun 23 17:06:55 1989
  12. cat << \SHAR_EOF > Remote_Makefile
  13. #    Makefile for the remote server for GDB, the GNU debugger.
  14. #    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
  15. # This file is part of GDB.
  16. # This program is free software; you can redistribute it and/or modify
  17. # it under the terms of the GNU General Public License as published by
  18. # the Free Software Foundation; either version 2 of the License, or
  19. # (at your option) any later version.
  20. # This program is distributed in the hope that it will be useful,
  21. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23. # GNU General Public License for more details.
  24. # You should have received a copy of the GNU General Public License
  25. # along with this program; if not, write to the Free Software
  26. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27.  
  28. CFLAGS = -g 
  29. CC = cc
  30.  
  31. SERVER = remote_server.o\
  32.          remote_inflow.o\
  33.          remote_utils.o\
  34.          remote_gutils.o 
  35.  
  36. prog : $(SERVER)
  37.     $(CC) -g -o serve $(SERVER) 
  38. SHAR_EOF
  39. cat << \SHAR_EOF > remote_gutils.c
  40. /* General utility routines for the remote server for GDB, the GNU debugger.
  41.    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
  42.  
  43. This file is part of GDB.
  44.  
  45. This program is free software; you can redistribute it and/or modify
  46. it under the terms of the GNU General Public License as published by
  47. the Free Software Foundation; either version 2 of the License, or
  48. (at your option) any later version.
  49.  
  50. This program is distributed in the hope that it will be useful,
  51. but WITHOUT ANY WARRANTY; without even the implied warranty of
  52. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  53. GNU General Public License for more details.
  54.  
  55. You should have received a copy of the GNU General Public License
  56. along with this program; if not, write to the Free Software
  57. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  58.  
  59. #include <stdio.h>
  60. #include <sys/ioctl.h>
  61. #include "defs.h"
  62.  
  63. void error ();
  64. void fatal ();
  65.  
  66. /* Chain of cleanup actions established with make_cleanup,
  67.    to be executed if an error happens.  */
  68.  
  69. static struct cleanup *cleanup_chain;
  70.  
  71. /* Nonzero means a quit has been requested.  */
  72.  
  73. int quit_flag;
  74.  
  75. /* Nonzero means quit immediately if Control-C is typed now,
  76.    rather than waiting until QUIT is executed.  */
  77.  
  78. int immediate_quit;
  79.  
  80. /* Add a new cleanup to the cleanup_chain,
  81.    and return the previous chain pointer
  82.    to be passed later to do_cleanups or discard_cleanups.
  83.    Args are FUNCTION to clean up with, and ARG to pass to it.  */
  84.  
  85. struct cleanup *
  86. make_cleanup (function, arg)
  87.      void (*function) ();
  88.      int arg;
  89. {
  90.   register struct cleanup *new
  91.     = (struct cleanup *) xmalloc (sizeof (struct cleanup));
  92.   register struct cleanup *old_chain = cleanup_chain;
  93.  
  94.   new->next = cleanup_chain;
  95.   new->function = function;
  96.   new->arg = arg;
  97.   cleanup_chain = new;
  98.  
  99.   return old_chain;
  100. }
  101.  
  102. /* Discard cleanups and do the actions they describe
  103.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  104.  
  105. void
  106. do_cleanups (old_chain)
  107.      register struct cleanup *old_chain;
  108. {
  109.   register struct cleanup *ptr;
  110.   while ((ptr = cleanup_chain) != old_chain)
  111.     {
  112.       (*ptr->function) (ptr->arg);
  113.       cleanup_chain = ptr->next;
  114.       free (ptr);
  115.     }
  116. }
  117.  
  118. /* Discard cleanups, not doing the actions they describe,
  119.    until we get back to the point OLD_CHAIN in the cleanup_chain.  */
  120.  
  121. void
  122. discard_cleanups (old_chain)
  123.      register struct cleanup *old_chain;
  124. {
  125.   register struct cleanup *ptr;
  126.   while ((ptr = cleanup_chain) != old_chain)
  127.     {
  128.       cleanup_chain = ptr->next;
  129.       free (ptr);
  130.     }
  131. }
  132.  
  133. /* This function is useful for cleanups.
  134.    Do
  135.  
  136.      foo = xmalloc (...);
  137.      old_chain = make_cleanup (free_current_contents, &foo);
  138.  
  139.    to arrange to free the object thus allocated.  */
  140.  
  141. void
  142. free_current_contents (location)
  143.      char **location;
  144. {
  145.   free (*location);
  146. }
  147.  
  148. /* Generally useful subroutines used throughout the program.  */
  149.  
  150. /* Like malloc but get error if no storage available.  */
  151.  
  152. char *
  153. xmalloc (size)
  154.      long size;
  155. {
  156.   register char *val = (char *) malloc (size);
  157.   if (!val)
  158.     fatal ("virtual memory exhausted.", 0);
  159.   return val;
  160. }
  161.  
  162. /* Like realloc but get error if no storage available.  */
  163.  
  164. char *
  165. xrealloc (ptr, size)
  166.      char *ptr;
  167.      long size;
  168. {
  169.   register char *val = (char *) realloc (ptr, size);
  170.   if (!val)
  171.     fatal ("virtual memory exhausted.", 0);
  172.   return val;
  173. }
  174.  
  175. /* Print the system error message for errno, and also mention STRING
  176.    as the file name for which the error was encountered.
  177.    Then return to command level.  */
  178.  
  179. void
  180. perror_with_name (string)
  181.      char *string;
  182. {
  183.   extern int sys_nerr;
  184.   extern char *sys_errlist[];
  185.   extern int errno;
  186.   char *err;
  187.   char *combined;
  188.  
  189.   if (errno < sys_nerr)
  190.     err = sys_errlist[errno];
  191.   else
  192.     err = "unknown error";
  193.  
  194.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  195.   strcpy (combined, string);
  196.   strcat (combined, ": ");
  197.   strcat (combined, err);
  198.  
  199.   error ("%s.", combined);
  200. }
  201.  
  202. /* Print the system error message for ERRCODE, and also mention STRING
  203.    as the file name for which the error was encountered.  */
  204.  
  205. void
  206. print_sys_errmsg (string, errcode)
  207.      char *string;
  208.      int errcode;
  209. {
  210.   extern int sys_nerr;
  211.   extern char *sys_errlist[];
  212.   char *err;
  213.   char *combined;
  214.  
  215.   if (errcode < sys_nerr)
  216.     err = sys_errlist[errcode];
  217.   else
  218.     err = "unknown error";
  219.  
  220.   combined = (char *) alloca (strlen (err) + strlen (string) + 3);
  221.   strcpy (combined, string);
  222.   strcat (combined, ": ");
  223.   strcat (combined, err);
  224.  
  225.   printf ("%s.\n", combined);
  226. }
  227.  
  228. void
  229. quit ()
  230. {
  231.   fflush (stdout);
  232.   ioctl (fileno (stdout), TIOCFLUSH, 0);
  233.   error ("Quit");
  234. }
  235.  
  236. /* Control C comes here */
  237.  
  238. void
  239. request_quit ()
  240. {
  241.   quit_flag = 1;
  242.   if (immediate_quit)
  243.     quit ();
  244. }
  245.  
  246. /* Print an error message and return to command level.
  247.    STRING is the error message, used as a fprintf string,
  248.    and ARG is passed as an argument to it.  */
  249.  
  250. void
  251. error (string, arg1, arg2, arg3)
  252.      char *string;
  253.      int arg1, arg2, arg3;
  254. {
  255.   fflush (stdout);
  256.   fprintf (stderr, string, arg1, arg2, arg3);
  257.   fprintf (stderr, "\n");
  258.   /************return_to_top_level ();************/ 
  259. }
  260.  
  261. /* Print an error message and exit reporting failure.
  262.    This is for a error that we cannot continue from.
  263.    STRING and ARG are passed to fprintf.  */
  264.  
  265. void
  266. fatal (string, arg)
  267.      char *string;
  268.      int arg;
  269. {
  270.   fprintf (stderr, "gdb: ");
  271.   fprintf (stderr, string, arg);
  272.   fprintf (stderr, "\n");
  273.   exit (1);
  274. }
  275.  
  276. /* Make a copy of the string at PTR with SIZE characters
  277.    (and add a null character at the end in the copy).
  278.    Uses malloc to get the space.  Returns the address of the copy.  */
  279.  
  280. char *
  281. savestring (ptr, size)
  282.      char *ptr;
  283.      int size;
  284. {
  285.   register char *p = (char *) xmalloc (size + 1);
  286.   bcopy (ptr, p, size);
  287.   p[size] = 0;
  288.   return p;
  289. }
  290.  
  291. char *
  292. concat (s1, s2, s3)
  293.      char *s1, *s2, *s3;
  294. {
  295.   register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
  296.   register char *val = (char *) xmalloc (len);
  297.   strcpy (val, s1);
  298.   strcat (val, s2);
  299.   strcat (val, s3);
  300.   return val;
  301. }
  302.  
  303. void
  304. print_spaces (n, file)
  305.      register int n;
  306.      register FILE *file;
  307. {
  308.   while (n-- > 0)
  309.     fputc (' ', file);
  310. }
  311.  
  312. /* Ask user a y-or-n question and return 1 iff answer is yes.
  313.    Takes three args which are given to printf to print the question.
  314.    The first, a control string, should end in "? ".
  315.    It should not say how to answer, because we do that.  */
  316.  
  317. int
  318. query (ctlstr, arg1, arg2)
  319.      char *ctlstr;
  320. {
  321.   register int answer;
  322.  
  323.   /* Automatically answer "yes" if input is not from a terminal.  */
  324.   /***********if (!input_from_terminal_p ())
  325.     return 1; *************************/ 
  326.  
  327.   while (1)
  328.     {
  329.       printf (ctlstr, arg1, arg2);
  330.       printf ("(y or n) ");
  331.       fflush (stdout);
  332.       answer = fgetc (stdin);
  333.       clearerr (stdin);        /* in case of C-d */
  334.       if (answer != '\n')
  335.     while (fgetc (stdin) != '\n') clearerr (stdin);
  336.       if (answer >= 'a')
  337.     answer -= 040;
  338.       if (answer == 'Y')
  339.     return 1;
  340.       if (answer == 'N')
  341.     return 0;
  342.       printf ("Please answer y or n.\n");
  343.     }
  344. }
  345.  
  346. /* Parse a C escape sequence.  STRING_PTR points to a variable
  347.    containing a pointer to the string to parse.  That pointer
  348.    is updated past the characters we use.  The value of the
  349.    escape sequence is returned.
  350.  
  351.    A negative value means the sequence \ newline was seen,
  352.    which is supposed to be equivalent to nothing at all.
  353.  
  354.    If \ is followed by a null character, we return a negative
  355.    value and leave the string pointer pointing at the null character.
  356.  
  357.    If \ is followed by 000, we return 0 and leave the string pointer
  358.    after the zeros.  A value of 0 does not mean end of string.  */
  359.  
  360. int
  361. parse_escape (string_ptr)
  362.      char **string_ptr;
  363. {
  364.   register int c = *(*string_ptr)++;
  365.   switch (c)
  366.     {
  367.     case 'a':
  368.       return '\a';
  369.     case 'b':
  370.       return '\b';
  371.     case 'e':
  372.       return 033;
  373.     case 'f':
  374.       return '\f';
  375.     case 'n':
  376.       return '\n';
  377.     case 'r':
  378.       return '\r';
  379.     case 't':
  380.       return '\t';
  381.     case 'v':
  382.       return '\v';
  383.     case '\n':
  384.       return -2;
  385.     case 0:
  386.       (*string_ptr)--;
  387.       return 0;
  388.     case '^':
  389.       c = *(*string_ptr)++;
  390.       if (c == '\\')
  391.     c = parse_escape (string_ptr);
  392.       if (c == '?')
  393.     return 0177;
  394.       return (c & 0200) | (c & 037);
  395.       
  396.     case '0':
  397.     case '1':
  398.     case '2':
  399.     case '3':
  400.     case '4':
  401.     case '5':
  402.     case '6':
  403.     case '7':
  404.       {
  405.     register int i = c - '0';
  406.     register int count = 0;
  407.     while (++count < 3)
  408.       {
  409.         if ((c = *(*string_ptr)++) >= '0' && c <= '7')
  410.           {
  411.         i *= 8;
  412.         i += c - '0';
  413.           }
  414.         else
  415.           {
  416.         (*string_ptr)--;
  417.         break;
  418.           }
  419.       }
  420.     return i;
  421.       }
  422.     default:
  423.       return c;
  424.     }
  425. }
  426.  
  427. void
  428. printchar (ch, stream)
  429.      unsigned char ch;
  430.      FILE *stream;
  431. {
  432.   register int c = ch;
  433.   if (c < 040 || c >= 0177)
  434.     {
  435.       if (c == '\n')
  436.     fprintf (stream, "\\n");
  437.       else if (c == '\b')
  438.     fprintf (stream, "\\b");
  439.       else if (c == '\t')
  440.     fprintf (stream, "\\t");
  441.       else if (c == '\f')
  442.     fprintf (stream, "\\f");
  443.       else if (c == '\r')
  444.     fprintf (stream, "\\r");
  445.       else if (c == 033)
  446.     fprintf (stream, "\\e");
  447.       else if (c == '\a')
  448.     fprintf (stream, "\\a");
  449.       else
  450.     fprintf (stream, "\\%03o", c);
  451.     }
  452.   else
  453.     {
  454.       if (c == '\\' || c == '"' || c == '\'')
  455.     fputc ('\\', stream);
  456.       fputc (c, stream);
  457.     }
  458. }
  459. SHAR_EOF
  460. cat << \SHAR_EOF > remote_inflow.c
  461. /* Low level interface to ptrace, for GDB when running under Unix.
  462.    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
  463. */
  464.  
  465. #include "defs.h"
  466. #include "param.h"
  467. #include "wait.h"
  468. #include "frame.h"
  469. #include "inferior.h"
  470. /***************************
  471. #include "initialize.h"
  472. ****************************/ 
  473.  
  474. #include <stdio.h>
  475. #include <sys/param.h>
  476. #include <sys/dir.h>
  477. #include <sys/user.h>
  478. #include <signal.h>
  479. #include <sys/ioctl.h>
  480. #include <sgtty.h>
  481. #include <fcntl.h>
  482.  
  483. /***************Begin MY defs*********************/ 
  484. int quit_flag = 0; 
  485. char registers[REGISTER_BYTES]; 
  486.  
  487. /* Index within `registers' of the first byte of the space for
  488.    register N.  */
  489.  
  490.  
  491. char buf2[MAX_REGISTER_RAW_SIZE];
  492. /***************End MY defs*********************/ 
  493.  
  494. #ifdef NEW_SUN_PTRACE
  495. #include <sys/ptrace.h>
  496. #include <machine/reg.h>
  497. #endif
  498.  
  499. extern char **environ; 
  500. extern int errno;
  501. extern int inferior_pid; 
  502. void error(), quit(), perror_with_name();
  503. int query(); 
  504. void supply_register(), write_register(); 
  505. CORE_ADDR read_register(); 
  506.  
  507. /* Nonzero if we are debugging an attached outside process
  508.    rather than an inferior.  */
  509.  
  510.  
  511. /* Start an inferior process and returns its pid.
  512.    ALLARGS is a vector of program-name and args.
  513.    ENV is the environment vector to pass.  */
  514.  
  515. int
  516. create_inferior (allargs, env)
  517.      char **allargs;
  518.      char **env;
  519. {
  520.   int pid;
  521.   extern int sys_nerr;
  522.   extern char *sys_errlist[];
  523.   extern int errno;
  524.  
  525.   /* exec is said to fail if the executable is open.  */
  526.   /****************close_exec_file ();*****************/ 
  527.  
  528.   pid = vfork ();
  529.   if (pid < 0)
  530.     perror_with_name ("vfork");
  531.  
  532.   if (pid == 0)
  533.     {
  534.       /* Run inferior in a separate process group.  */
  535.       setpgrp (getpid (), getpid ());
  536.  
  537. /* Not needed on Sun, at least, and loses there
  538.    because it clobbers the superior.  */
  539. /*???      signal (SIGQUIT, SIG_DFL);
  540.       signal (SIGINT, SIG_DFL);  */
  541.  
  542.       errno = 0; 
  543.       ptrace (0);
  544.  
  545.       execle ("/bin/sh", "sh", "-c", allargs, 0, env);
  546.  
  547.       fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
  548.            errno < sys_nerr ? sys_errlist[errno] : "unknown error");
  549.       fflush (stderr);
  550.       _exit (0177);
  551.     }
  552.   return pid;
  553. }
  554.  
  555. /* Kill the inferior process.  Make us have no inferior.  */
  556.  
  557. kill_inferior ()
  558. {
  559.   if (inferior_pid == 0)
  560.     return;
  561.   ptrace (8, inferior_pid, 0, 0);
  562.   wait (0);
  563.   /*************inferior_died ();****VK**************/ 
  564. }
  565.  
  566. /* Resume execution of the inferior process.
  567.    If STEP is nonzero, single-step it.
  568.    If SIGNAL is nonzero, give it that signal.  */
  569.  
  570. unsigned char
  571. resume (step, signal,status)
  572.      int step;
  573.      int signal;
  574.      char *status; 
  575. {
  576.     int pid ; 
  577.     WAITTYPE w; 
  578.  
  579.       errno = 0;
  580.     ptrace (step ? 9 : 7, inferior_pid, 1, signal);
  581.     if (errno)
  582.         perror_with_name ("ptrace");
  583.     pid = wait(&w); 
  584.     if(pid != inferior_pid) 
  585.         perror_with_name ("wait"); 
  586.  
  587.     if(WIFEXITED(w))
  588.     {
  589.         printf("\nchild exited with retcode = %x \n",WRETCODE(w)); 
  590.         *status = 'E'; 
  591.         return((unsigned char) WRETCODE(w));
  592.     } 
  593.     else if(!WIFSTOPPED(w))
  594.     {
  595.         printf("\nchild did terminated with signal = %x \n",WTERMSIG(w)); 
  596.         *status = 'T'; 
  597.         return((unsigned char) WTERMSIG(w)); 
  598.     } 
  599.     else 
  600.     {
  601.         printf("\nchild stopped with signal = %x \n",WSTOPSIG(w)); 
  602.         *status = 'S'; 
  603.         return((unsigned char) WSTOPSIG(w)); 
  604.     } 
  605.          
  606. }
  607.  
  608.  
  609. #ifdef NEW_SUN_PTRACE
  610.  
  611. void
  612. fetch_inferior_registers ()
  613. {
  614.   struct regs inferior_registers;
  615.   struct fp_status inferior_fp_registers;
  616.   extern char registers[];
  617.  
  618.       ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
  619.       if (errno)
  620.         perror_with_name ("ptrace");
  621.       /**********debugging begin **********/ 
  622.       print_some_registers(&inferior_registers); 
  623.       /**********debugging end **********/ 
  624.       ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
  625.       if (errno)
  626.         perror_with_name ("ptrace");
  627.  
  628.       bcopy (&inferior_registers, registers, 16 * 4);
  629.       bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)],
  630.          sizeof inferior_fp_registers.fps_regs);
  631.       *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
  632.       *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
  633.       bcopy (&inferior_fp_registers.fps_control,
  634.          ®isters[REGISTER_BYTE (FPC_REGNUM)],
  635.          sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
  636. }
  637.  
  638. /* Store our register values back into the inferior.
  639.    If REGNO is -1, do this for all registers.
  640.    Otherwise, REGNO specifies which register (so we can save time).  */
  641.  
  642. store_inferior_registers (regno)
  643.      int regno;
  644. {
  645.   struct regs inferior_registers;
  646.   struct fp_status inferior_fp_registers;
  647.   extern char registers[];
  648.  
  649.       bcopy (registers, &inferior_registers, 16 * 4);
  650.       bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
  651.          sizeof inferior_fp_registers.fps_regs);
  652.       inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)];
  653.       inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)];
  654.       bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)],
  655.          &inferior_fp_registers.fps_control,
  656.          sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
  657.  
  658.       ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
  659.       if (errno)
  660.         perror_with_name ("ptrace");
  661.       ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
  662.       if (errno)
  663.         perror_with_name ("ptrace");
  664. }
  665.  
  666. #endif /* not NEW_SUN_PTRACE */
  667.  
  668.  
  669. /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
  670.    in the NEW_SUN_PTRACE case.
  671.    It ought to be straightforward.  But it appears that writing did
  672.    not write the data that I specified.  I cannot understand where
  673.    it got the data that it actually did write.  */
  674.  
  675. /* Copy LEN bytes from inferior's memory starting at MEMADDR
  676.    to debugger memory starting at MYADDR.  */
  677.  
  678. read_inferior_memory (memaddr, myaddr, len)
  679.      CORE_ADDR memaddr;
  680.      char *myaddr;
  681.      int len;
  682. {
  683.   register int i;
  684.   /* Round starting address down to longword boundary.  */
  685.   register CORE_ADDR addr = memaddr & - sizeof (int);
  686.   /* Round ending address up; get number of longwords that makes.  */
  687.   register int count
  688.     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  689.   /* Allocate buffer of that many longwords.  */
  690.   register int *buffer = (int *) alloca (count * sizeof (int));
  691.  
  692.   /* Read all the longwords */
  693.   for (i = 0; i < count; i++, addr += sizeof (int))
  694.     {
  695.     buffer[i] = ptrace (1, inferior_pid, addr, 0);
  696.     }
  697.  
  698.   /* Copy appropriate bytes out of the buffer.  */
  699.   bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
  700. }
  701.  
  702. /* Copy LEN bytes of data from debugger memory at MYADDR
  703.    to inferior's memory at MEMADDR.
  704.    On failure (cannot write the inferior)
  705.    returns the value of errno.  */
  706.  
  707. int
  708. write_inferior_memory (memaddr, myaddr, len)
  709.      CORE_ADDR memaddr;
  710.      char *myaddr;
  711.      int len;
  712. {
  713.   register int i;
  714.   /* Round starting address down to longword boundary.  */
  715.   register CORE_ADDR addr = memaddr & - sizeof (int);
  716.   /* Round ending address up; get number of longwords that makes.  */
  717.   register int count
  718.     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
  719.   /* Allocate buffer of that many longwords.  */
  720.   register int *buffer = (int *) alloca (count * sizeof (int));
  721.   extern int errno;
  722.  
  723.   /* Fill start and end extra bytes of buffer with existing memory data.  */
  724.  
  725.     buffer[0] = ptrace (1, inferior_pid, addr, 0);
  726.  
  727.   if (count > 1)
  728.     {
  729.     buffer[count - 1]
  730.       = ptrace (1, inferior_pid,
  731.             addr + (count - 1) * sizeof (int), 0);
  732.     }
  733.  
  734.   /* Copy data to be written over corresponding part of buffer */
  735.  
  736.   bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
  737.  
  738.   /* Write the entire buffer.  */
  739.  
  740.   for (i = 0; i < count; i++, addr += sizeof (int))
  741.     {
  742.       errno = 0;
  743.     ptrace (4, inferior_pid, addr, buffer[i]);
  744.       if (errno)
  745.     return errno;
  746.     }
  747.  
  748.   return 0;
  749. }
  750.  
  751. void
  752. try_writing_regs_command ()
  753. {
  754.   register int i;
  755.   register int value;
  756.   extern int errno;
  757.  
  758.   if (inferior_pid == 0)
  759.     error ("There is no inferior process now.");
  760.  
  761.   fetch_inferior_registers(); 
  762.   for (i = 0;i<18 ; i ++)
  763.     {
  764.       QUIT;
  765.       errno = 0;
  766.       value = read_register(i); 
  767.       write_register ( i, value);
  768.       if (errno == 0)
  769.     {
  770.           printf (" Succeeded with register %d; value 0x%x (%d).\n",
  771.           i, value, value);
  772.     }
  773.       else 
  774.         printf (" Failed with register %d.\n", i);
  775.     }
  776. }
  777.  
  778. void
  779. initialize ()
  780. {
  781.  
  782.   inferior_pid = 0;
  783.  
  784.  
  785. }
  786.  
  787.  
  788. /* Return the contents of register REGNO,
  789.    regarding it as an integer.  */
  790.  
  791. CORE_ADDR
  792. read_register (regno)
  793.      int regno;
  794. {
  795.   /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
  796.   return *(int *) ®isters[REGISTER_BYTE (regno)];
  797. }
  798.  
  799. /* Store VALUE in the register number REGNO, regarded as an integer.  */
  800.  
  801. void
  802. write_register (regno, val)
  803.      int regno, val;
  804. {
  805.   /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
  806.   *(int *) ®isters[REGISTER_BYTE (regno)] = val;
  807.  
  808.   if (have_inferior_p ())
  809.     store_inferior_registers (regno);
  810. }
  811.  
  812.  
  813. int
  814. have_inferior_p ()
  815. {
  816.   return inferior_pid != 0;
  817. }
  818.  
  819. print_some_registers(regs)
  820. int regs[];
  821. {
  822.    register int i;
  823.    for (i = 0; i < 18; i++) {
  824.      printf("reg[%d] = %x\n", i, regs[i]);
  825.      }
  826. }
  827.  
  828. SHAR_EOF
  829. cat << \SHAR_EOF > remote_server.c
  830. /* Main code for remote server for GDB, the GNU Debugger.
  831.    Copyright (C) 1989 Free Software Foundation, Inc.
  832.  
  833. This file is part of GDB.
  834.  
  835. This program is free software; you can redistribute it and/or modify
  836. it under the terms of the GNU General Public License as published by
  837. the Free Software Foundation; either version 2 of the License, or
  838. (at your option) any later version.
  839.  
  840. This program is distributed in the hope that it will be useful,
  841. but WITHOUT ANY WARRANTY; without even the implied warranty of
  842. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  843. GNU General Public License for more details.
  844.  
  845. You should have received a copy of the GNU General Public License
  846. along with this program; if not, write to the Free Software
  847. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  848.  
  849. #include "param.h"
  850. #include <stdio.h>
  851.  
  852. void read_inferior_memory(), fetch_inferior_registers(); 
  853. unsigned char resume(); 
  854. void kill_inferior(); 
  855. void initialize(), try_writing_regs_command();  
  856. int create_inferior(), read_register(); 
  857.  
  858. extern char registers[]; 
  859. int inferior_pid; 
  860. extern char **environ; 
  861.  
  862. /* Descriptor for I/O to remote machine.  */
  863. int remote_desc;
  864. int kiodebug = 0;
  865. int remote_debugging; 
  866.  
  867. void remote_send ();
  868. void putpkt ();
  869. void getpkt ();
  870. void remote_open(); 
  871. void write_ok(); 
  872. void write_enn(); 
  873. void convert_ascii_to_int(); 
  874. void convert_int_to_ascii(); 
  875. void prepare_resume_reply(); 
  876. void decode_m_packet(); 
  877. void decode_M_packet(); 
  878.  
  879.  
  880. main(argc,argv)
  881. int argc; char *argv[]; 
  882. {
  883.     char ch,status, own_buf[2000], mem_buf[2000]; 
  884.     int i=0;  
  885.     unsigned char signal;  
  886.     unsigned int mem_addr, len; 
  887.  
  888.     initialize(); 
  889.     printf("\nwill open serial link\n"); 
  890.     remote_open("/dev/ttya",0); 
  891.  
  892.     if(argc < 2) 
  893.     { 
  894.         printf("Enter name of program to be run with command line args\n"); 
  895.         gets(own_buf); 
  896.         inferior_pid = create_inferior(own_buf,environ); 
  897.         printf("\nProcess %s created; pid = %d\n",own_buf,inferior_pid);
  898.     } 
  899.     else 
  900.     { 
  901.         inferior_pid = create_inferior(argv[1],environ); 
  902.         printf("\nProcess %s created; pid = %d\n",argv[1],inferior_pid);
  903.     } 
  904.  
  905.     do {  
  906.         getpkt(own_buf); 
  907.         printf("\nPacket received is>:%s\n",own_buf); 
  908.         i = 0; 
  909.         ch = own_buf[i++]; 
  910.         switch (ch) { 
  911.             case 'h':    /**********This is only for tweaking the gdb+ program *******/ 
  912.                         signal = resume(1,0,&status);
  913.                         prepare_resume_reply(own_buf,status,signal); 
  914.                         break; 
  915.                         /*************end tweak*************************************/ 
  916.  
  917.             case 'g':    fetch_inferior_registers();         
  918.                         convert_int_to_ascii(registers,own_buf,REGISTER_BYTES); 
  919.                         break; 
  920.             case 'G':    convert_ascii_to_int(&own_buf[1],registers,REGISTER_BYTES);
  921.                         if(store_inferior_registers(-1)==0)  
  922.                             write_ok(own_buf); 
  923.                         else  
  924.                             write_enn(own_buf); 
  925.                         break; 
  926.             case 'm':    decode_m_packet(&own_buf[1],&mem_addr,&len); 
  927.                         read_inferior_memory(mem_addr,mem_buf,len);
  928.                         convert_int_to_ascii(mem_buf,own_buf,len); 
  929.                         break; 
  930.             case 'M':    decode_M_packet(&own_buf[1],&mem_addr,&len,mem_buf); 
  931.                         if(write_inferior_memory(mem_addr,mem_buf,len)==0)  
  932.                             write_ok(own_buf); 
  933.                         else 
  934.                             write_enn(own_buf); 
  935.                         break; 
  936.             case 'c':    signal = resume(0,0,&status);
  937.                         printf("\nSignal received is >: %0x \n",signal); 
  938.                         prepare_resume_reply(own_buf,status,signal); 
  939.                         break; 
  940.             case 's':    signal = resume(1,0,&status);
  941.                         prepare_resume_reply(own_buf,status,signal); 
  942.                         break; 
  943.             case 'k':    kill_inferior();
  944.                         sprintf(own_buf,"q"); 
  945.                         putpkt(own_buf); 
  946.                         printf("\nObtained kill request...terminating\n"); 
  947.                          close(remote_desc); 
  948.                         exit(0); 
  949.             case 't':    try_writing_regs_command();
  950.                         own_buf[0] = '\0'; 
  951.                         break; 
  952.             default :    printf("\nUnknown option chosen by master\n"); 
  953.                         write_enn(own_buf); 
  954.                         break; 
  955.            } 
  956.  
  957.         putpkt(own_buf); 
  958.      }  while(1) ; 
  959.  
  960.     close(remote_desc); 
  961.     /** now get out of here**/ 
  962.     printf("\nFinished reading data from serial link - Bye!\n"); 
  963.     exit(0);
  964.  
  965. }
  966.  
  967. SHAR_EOF
  968. cat << \SHAR_EOF > remote_utils.c
  969. /* Remote utility routines for the remote server for GDB, the GNU debugger.
  970.    Copyright (C) 1986, 1989 Free Software Foundation, Inc.
  971.  
  972. This file is part of GDB.
  973.  
  974. This program is free software; you can redistribute it and/or modify
  975. it under the terms of the GNU General Public License as published by
  976. the Free Software Foundation; either version 2 of the License, or
  977. (at your option) any later version.
  978.  
  979. This program is distributed in the hope that it will be useful,
  980. but WITHOUT ANY WARRANTY; without even the implied warranty of
  981. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  982. GNU General Public License for more details.
  983.  
  984. You should have received a copy of the GNU General Public License
  985. along with this program; if not, write to the Free Software
  986. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  987.  
  988. #include "param.h"
  989. #include <stdio.h>
  990. #include <signal.h>
  991. #include <sys/wait.h>
  992. #include <sys/ioctl.h>
  993. #include <a.out.h>
  994. #include <sys/file.h>
  995. #include <sgtty.h> 
  996.  
  997. extern int remote_desc; 
  998. extern int remote_debugging; 
  999. extern int kiodebug; 
  1000.  
  1001. void remote_open(); 
  1002. void remote_send(); 
  1003. void putpkt(); 
  1004. void getpkt(); 
  1005.  
  1006. void write_ok(); 
  1007. void write_enn(); 
  1008. void convert_ascii_to_int(); 
  1009. void convert_int_to_ascii(); 
  1010. void prepare_resume_reply(); 
  1011.  
  1012. /* Open a connection to a remote debugger.
  1013.    NAME is the filename used for communication.  */
  1014.  
  1015. void
  1016. remote_open (name, from_tty)
  1017.      char *name;
  1018.      int from_tty;
  1019. {
  1020.   struct sgttyb sg;
  1021.  
  1022.   remote_debugging = 0;
  1023.  
  1024.   remote_desc = open (name, O_RDWR);
  1025.   if (remote_desc < 0)
  1026.     printf("\ncould not open remote device\n"); 
  1027.  
  1028.   ioctl (remote_desc, TIOCGETP, &sg);
  1029.   sg.sg_flags = RAW;
  1030.   ioctl (remote_desc, TIOCSETP, &sg);
  1031.  
  1032.   if (from_tty)
  1033.     printf ("Remote debugging using %s\n", name);
  1034.   remote_debugging = 1;
  1035. }
  1036.  
  1037. /* Convert hex digit A to a number.  */
  1038.  
  1039. static int
  1040. fromhex (a)
  1041.      int a;
  1042. {
  1043.   if (a >= '0' && a <= '9')
  1044.     return a - '0';
  1045.   else if (a >= 'a' && a <= 'f')
  1046.     return a - 'a' + 10;
  1047.   else
  1048.     perror ("Reply contains invalid hex digit");
  1049. }
  1050.  
  1051. /* Convert number NIB to a hex digit.  */
  1052.  
  1053. static int
  1054. tohex (nib)
  1055.      int nib;
  1056. {
  1057.   if (nib < 10)
  1058.     return '0'+nib;
  1059.   else
  1060.     return 'a'+nib-10;
  1061. }
  1062.  
  1063. /* Send the command in BUF to the remote machine,
  1064.    and read the reply into BUF.
  1065.    Report an error if we get an error reply.  */
  1066.  
  1067. void
  1068. remote_send (buf)
  1069.      char *buf;
  1070. {
  1071.   putpkt (buf);
  1072.   getpkt (buf);
  1073.  
  1074.   if (buf[0] == 'E')
  1075.     perror ("Remote failure reply: %s", buf);
  1076. }
  1077.  
  1078. /* Send a packet to the remote machine, with error checking.
  1079.    The data of the packet is in BUF.  */
  1080.  
  1081. void
  1082. putpkt (buf)
  1083.      char *buf;
  1084. {
  1085.   int i;
  1086.   unsigned char csum = 0;
  1087.   char buf2[500];
  1088.   char buf3[1];
  1089.   int cnt = strlen (buf);
  1090.   char *p;
  1091.  
  1092.   if (kiodebug)
  1093.     fprintf (stderr, "Sending packet: %s\n", buf);
  1094.  
  1095.   /* Copy the packet into buffer BUF2, encapsulating it
  1096.      and giving it a checksum.  */
  1097.  
  1098.   p = buf2;
  1099.   *p++ = '$';
  1100.  
  1101.   for (i = 0; i < cnt; i++)
  1102.     {
  1103.       csum += buf[i];
  1104.       *p++ = buf[i];
  1105.     }
  1106.   *p++ = '#';
  1107.   *p++ = tohex ((csum >> 4) & 0xf);
  1108.   *p++ = tohex (csum & 0xf);
  1109.  
  1110.   /* Send it over and over until we get a positive ack.  */
  1111.  
  1112.   do {
  1113.     write (remote_desc, buf2, p - buf2);
  1114.     read (remote_desc, buf3, 1);
  1115.   } while (buf3[0] != '+');
  1116. }
  1117.  
  1118. static int
  1119. readchar ()
  1120. {
  1121.   char buf[1];
  1122.   while (read (remote_desc, buf, 1) != 1) ;
  1123.   return buf[0] & 0x7f;
  1124. }
  1125.  
  1126. /* Read a packet from the remote machine, with error checking,
  1127.    and store it in BUF.  */
  1128.  
  1129. void
  1130. getpkt (buf)
  1131.      char *buf;
  1132. {
  1133.   char *bp;
  1134.   unsigned char csum, c, c1, c2;
  1135.   extern kiodebug;
  1136.  
  1137.   while (1)
  1138.     {
  1139.       csum = 0; 
  1140.       while ((c = readchar()) != '$');
  1141.  
  1142.       bp = buf;
  1143.       while (1)
  1144.     {
  1145.       c = readchar ();
  1146.       if (c == '#')
  1147.         break;
  1148.       *bp++ = c;
  1149.       csum += c;
  1150.     }
  1151.       *bp = 0;
  1152.  
  1153.       c1 = fromhex (readchar ());
  1154.       c2 = fromhex (readchar ());
  1155.       if (csum == (c1 << 4) + c2)
  1156.         break;
  1157.  
  1158.       printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
  1159.           (c1 << 4) + c2, csum, buf);
  1160.       write (remote_desc, "-", 1);
  1161.     }
  1162.  
  1163.   write (remote_desc, "+", 1);
  1164.  
  1165.   if (kiodebug)
  1166.     fprintf (stderr,"Packet received :%s\n", buf);
  1167. }
  1168.  
  1169.  
  1170. void 
  1171. write_ok(buf)
  1172.     char *buf; 
  1173. {
  1174.     buf[0] = 'O';
  1175.     buf[1] = 'k';
  1176.     buf[2] = '\0';
  1177. }
  1178.  
  1179. void 
  1180. write_enn(buf)
  1181.     char *buf; 
  1182. {
  1183.     buf[0] = 'E';
  1184.     buf[1] = 'N';
  1185.     buf[2] = 'N';
  1186.     buf[3] = '\0';
  1187. }
  1188.  
  1189. void
  1190. convert_int_to_ascii(from,to,n)
  1191. char *from, *to; int n; 
  1192. {
  1193.      int nib ; 
  1194.     char ch; 
  1195.     while( n-- )
  1196.     {
  1197.         ch = *from++;         
  1198.         nib = ((ch & 0xf0) >> 4)& 0x0f; 
  1199.         *to++ = tohex(nib); 
  1200.         nib = ch & 0x0f; 
  1201.         *to++ = tohex(nib); 
  1202.     } 
  1203.     *to++ = 0; 
  1204. }
  1205.  
  1206.  
  1207. void
  1208. convert_ascii_to_int(from,to,n)
  1209. char *from, *to; int n;  
  1210. {
  1211.      int nib1,nib2 ; 
  1212.     while( n-- )
  1213.     {
  1214.         nib1 = fromhex(*from++); 
  1215.         nib2 = fromhex(*from++); 
  1216.         *to++ = (((nib1 & 0x0f)<< 4)& 0xf0) | (nib2 & 0x0f); 
  1217.     } 
  1218. }
  1219.  
  1220. void
  1221. prepare_resume_reply(buf,status,signal)
  1222. char *buf ,status; 
  1223. unsigned char signal; 
  1224. {
  1225.      int nib; 
  1226.     char ch; 
  1227.  
  1228.     *buf++ = 'S';  
  1229.     *buf++ = status;  
  1230.     nib = ((signal & 0xf0) >> 4) ; 
  1231.     *buf++ = tohex(nib); 
  1232.     nib = signal & 0x0f; 
  1233.     *buf++ = tohex(nib); 
  1234.     *buf++ = 0; 
  1235. }
  1236.  
  1237. void 
  1238. decode_m_packet(from,mem_addr_ptr,len_ptr)
  1239. char *from;
  1240. unsigned int *mem_addr_ptr, *len_ptr; 
  1241. {
  1242.     int i = 0, j = 0 ; 
  1243.     char ch; 
  1244.     *mem_addr_ptr = *len_ptr = 0; 
  1245.     /************debugging begin************/ 
  1246.     printf("\nIn decode_m_packet"); 
  1247.     /************debugging end************/ 
  1248.  
  1249.     while((ch = from[i++]) != ',') 
  1250.     { 
  1251.         *mem_addr_ptr = *mem_addr_ptr << 4; 
  1252.         *mem_addr_ptr |= fromhex(ch) & 0x0f; 
  1253.     } 
  1254.     /************debugging begin************/ 
  1255.     printf("\nFinished mem_addr part"); 
  1256.     /************debugging end************/ 
  1257.  
  1258.     for(j=0; j < 4; j++) 
  1259.     { 
  1260.         if((ch = from[i++]) == 0)  
  1261.             break; 
  1262.         *len_ptr = *len_ptr << 4; 
  1263.         *len_ptr |= fromhex(ch) & 0x0f; 
  1264.     } 
  1265.     /************debugging begin************/ 
  1266.     printf("\nFinished len_ptr part"); 
  1267.     /************debugging end************/ 
  1268. }
  1269.  
  1270. void 
  1271. decode_M_packet(from,mem_addr_ptr,len_ptr,to)
  1272. char *from, *to;
  1273. unsigned int *mem_addr_ptr, *len_ptr; 
  1274. {
  1275.     int i = 0, j = 0 ; 
  1276.     char ch; 
  1277.     *mem_addr_ptr = *len_ptr = 0; 
  1278.     /************debugging begin************/ 
  1279.     printf("\nIn decode_M_packet"); 
  1280.     /************debugging end************/ 
  1281.  
  1282.     while((ch = from[i++]) != ',') 
  1283.     { 
  1284.         *mem_addr_ptr = *mem_addr_ptr << 4; 
  1285.         *mem_addr_ptr |= fromhex(ch) & 0x0f; 
  1286.     } 
  1287.     /************debugging begin************/ 
  1288.     printf("\nFinished mem_addr part: memaddr = %x",*mem_addr_ptr); 
  1289.     /************debugging end************/ 
  1290.  
  1291.     while((ch = from[i++]) != ':') 
  1292.     { 
  1293.         *len_ptr = *len_ptr << 4; 
  1294.         *len_ptr |= fromhex(ch) & 0x0f; 
  1295.     } 
  1296.     /************debugging begin************/ 
  1297.     printf("\nFinished len_ptr part: len = %d",*len_ptr); 
  1298.     /************debugging end************/ 
  1299.  
  1300.     convert_ascii_to_int(&from[i++],to,*len_ptr); 
  1301.  
  1302.     /************debugging begin************/ 
  1303.     printf("\nmembuf : %x",*(int *)to); 
  1304.     /************debugging end************/ 
  1305. }
  1306.  
  1307. SHAR_EOF
  1308. #    End of shell archive
  1309. exit 0
  1310.